#include "transContentPortRegist.hpp"

/////////////////////////////////////////////////////////////////
/// deal the stack response regsit message
///		get registed result, resigst port and other information from the packet
///
/// parameters:
///		buffer: the response buffer
///		index: the response buffer index in memory pool
///
/// return:
///		RESPONSE_RESULT_DELETE_RECORD: despose the regist instance, and free the relative port record
///		RESPONSE_RESULT_CHANGE_STATE: change the regits instance relative state to registed
///		RESPONSE_RESULT_NOACTION: no action
///////////////////////////////////////////////////////////////////
int TransContentPortRegist::response(char* buffer, int index){
	int mainCode, subCode;
	mainCode = transContentRegistProtocol::getPacketMainMessageCode(buffer, DUMP_PROTOCOL_PACKET_IN);
	if(mainCode != message_type_inner_regist_response){
		logd_error("port regist response, not support main code");
		return RESPONSE_RESULT_POST_CONITNUE;
	}

	mRegistResult = transContentRegistProtocol::getPacketResult(buffer, DUMP_PROTOCOL_PACKET_IN);
	subCode = transContentRegistProtocol::getPacketSubMessage(buffer, DUMP_PROTOCOL_PACKET_IN);
	mRegistedPort = transContentRegistProtocol::getPacketResultPort(buffer, DUMP_PROTOCOL_PACKET_IN);
	return RESPONSE_RESULT_CHANGE_STATE;
}

/////////////////////////////////////////////////////////////////////
/// construct regist packet and send to stack
///		call regist protocol methods to make a regist packet and send to stack, get a port, check a port, or regist a port call this method
///
/// return:
///		E_TRANC_TIMEOUT: wait timeout
///		E_TRANC_NONBLOCK: call sync mthod, so will not block the caller
///		port: the regsit result port
///////////////////////////////////////////////////////////////////////
int TransContentPortRegist::regist(){
	/// construct packet
	char* buffer;
	int recordIndex=0;
	int length = 0;
	timespec ts = TransContentAssis::TimeTp2Ts(mTimeout);
	const char* localFifoName = TransContentSetting::getLocalFifoName();
	recordIndex = TransContentMemory::getInstance()->getBuffer(&buffer);
	if(E_TRANC_BUFFER_FULL == recordIndex){
		log_error("get space for regist failed, no buffer avaliable");
		return recordIndex;
	}

	transContentRegistProtocol::setPacketMainMessageCode(buffer, message_type_inner_regist_request);
	transContentRegistProtocol::setPacketSubMessage(buffer, mRegistingType);
	transContentRegistProtocol::setPacketTargetPort(buffer, mRegistingPort);
	transContentRegistProtocol::setPacketExistPort(buffer, mAlreadyPort);
	if(mAlreadyPort == -1){
		length = strlen(localFifoName);
		transContentRegistProtocol::setPacketPathLen(buffer, length);
		transContentRegistProtocol::setPacketPathValue(buffer, localFifoName, length);
	}
	length += 17;
	transContentRegistProtocol::setPacketLength(buffer, length);

	/// send to stack
	if(TransContentDispatcher::getInstance()->sendDataRegistToStack(buffer, length+2) != E_TRANC_SUCESS){
		log_error("send regist data to stack error!!");
		TransContentMemory::getInstance()->releaseBuffer(recordIndex);
		return E_TRANC_SystemError;
	}
	TransContentMemory::getInstance()->releaseBuffer(recordIndex);
	
	pthread_mutex_lock(&mutex_regist);	
	pthread_cond_wait(&waitCond, &waitMutex)
	pthread_mutex_unlock(&mutex_regist);

	if(returnType == REGIST_TETURN_PORT){
		return mRegistedPort == -1 ? canBeRemoved=1, mRegistResult : mRegistedPort;
	}else if(returnType == REGIST_RETURN_EXIST){
		canBeRemoved=1;
		return mRegistResult;
	}else{
		return mRegistResult==1?vid: canBeRemoved=1, mRegistResult;
	}
}
